﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using StockFinder.IBD.MarketSmithScreenService;
using StockFinder.Indicators.Day.ClosePrice;
using StockFinder.Model;
using StockFinder.Network;
using StockFinder.Services.Extractors;
using StockFinder.Services.Extractors.Yahoo;
using StockFinder.Services.PriceAnalysis;
using StockFinder.Model.Enumerations;
using StockFinder.DataAccess;
using System.Diagnostics;
using System.Net;
using System.IO;
using StockFinder.Services.Extractors.MarketSmith;
using StockFinder.Services.PriceAnalysis.Weekly;
using StockFinder.Services.Engines;
using Db4objects.Db4o;
using StockFinder.Model.Constants;
using Db4objects.Db4o.Config;
using log4net;
using StockFinder.Services.PriceDatabaseAnalysers;
using System.ServiceProcess;
using System.Threading;
using StockFinder.Services.StockPerformance;
using System.Net.Mail;
using StockFinder.Services.Brokers;
using StockFinder.NorgatePremiumData;

namespace Testharness
{
    public partial class Form2 : Form
    {
        private static readonly ILog _Log = LogManager.GetLogger(typeof(Form2));
        IHistoricPricesExtractor _YahooricesExtractor = new YahooHistoricPriceExtractor();

        public Form2()
        {
            InitializeComponent();
        }

        private void _SingleStockJustBrokenOutTestButton_Click(object sender, EventArgs e)
        {
            string name = "PZZI";

            Symbol symbol = new Symbol();
            symbol.Name = name;

            //1 load prices from yahoo
            IHistoricPricesExtractor _YahooricesExtractor = new YahooHistoricPriceExtractor();
            HistoricPricesExtract result = _YahooricesExtractor.ExtractHistoricPrices(
                DateTime.Now.AddYears(-20), DateTime.Today, symbol.Name);

            if (result.HistoricPricesExtractResult == StockFinder.Model.Enumerations.HistoricPricesExtractResult.SUCCESS)
            {
                //2 order the prices by date
                IOrderedEnumerable<DailyPrice> orderedPrices = result.DailyPrices.OrderByDescending(price => price.PriceDate);

                //3 run the analysis                
                IPriceAnalyser hasJustBrokenOutPriceAnalyser = new JustBrokenOutPriceAnalyser();
                PriceAnalysisResult priceAnalysisResult = hasJustBrokenOutPriceAnalyser.RunAnalysis(orderedPrices);


            }
        }

        private void _ROSTJustBrokenOutTest_Click(object sender, EventArgs e)
        {
            /* just broken out to all time high happens when the last close
             * is higher than all time high from previous prices.
             * diagnostics are:
             * 1 - previous all time high
             * 2 - time in base since that all time high
             * 3 - low of the base
             * 4 - depth of the base
             **/

            const string symbolName = "SWI";
            DateTime dateBrokeOut = new DateTime(2011, 10, 31);
            Symbol symbol = new Symbol{Name=symbolName};

            //1. get historical prices
            IHistoricPricesExtractor _YahooricesExtractor = new YahooHistoricPriceExtractor();

            //get price history
            HistoricPricesExtract historicPriceExtract = _YahooricesExtractor.ExtractHistoricPrices(
                DateTime.Now.AddYears(-20), DateTime.Today, symbol.Name);

            if (historicPriceExtract.HistoricPricesExtractResult == HistoricPricesExtractResult.SUCCESS)
            {               
                //get prices upto breakout day
                IOrderedEnumerable<DailyPrice> brokenOutPrices = historicPriceExtract.DailyPrices
                    .Where(i => i.PriceDate <= dateBrokeOut)
                    .OrderByDescending(price => price.PriceDate);

                /* is the previouse close higher than any previous high */

                //get last price
                DailyPrice lastPrice = brokenOutPrices.ElementAt(0);

                //get all time high before today
                DailyPrice allTimeHigh = brokenOutPrices.Skip(1).AllTimeHighestPriceByAdjustedHigh();

                //is the last price close higher than the previous all time high?
                if (lastPrice.AdjustedClose > allTimeHigh.AdjustedHigh)
                {
                    //yes we have broken out, now get base details
                    //4. get all prices since all time high
                    IEnumerable<DailyPrice> baseSinceAllTimeHigh = brokenOutPrices.Where(i => i.PriceDate >= allTimeHigh.PriceDate);

                    //5. make sure there are no 0 prices
                    if (!baseSinceAllTimeHigh.Any(i => i.AdjustedLow == 0))
                    {
                        //6. get the low of the base
                        decimal baseLow = baseSinceAllTimeHigh.Min(i => i.AdjustedLow);

                        //7. the daily price for that low
                        DailyPrice baseLowPrice = baseSinceAllTimeHigh.First(i => i.AdjustedLow == baseLow);

                        TimeSpan timeInBase = lastPrice.PriceDate - allTimeHigh.PriceDate;

                        int daysInBase = Convert.ToInt32(timeInBase.TotalDays);

                        //determine the base depth
                        decimal baseDepth = (allTimeHigh.AdjustedHigh - baseLow) / allTimeHigh.AdjustedHigh;
                    }
                }                                
            }
        }

        private void _ROSTPriceWithinWindowButton_Click(object sender, EventArgs e)
        {
            /* get the all time high */

            const string symbolName = "ROST";
            Symbol symbol = new Symbol { Name = symbolName };

            //1. get historical prices
            IHistoricPricesExtractor _YahooricesExtractor = new YahooHistoricPriceExtractor();

            HistoricPricesExtract historicPriceExtract = _YahooricesExtractor.ExtractHistoricPrices(
                DateTime.Now.AddYears(-20), DateTime.Today, symbol.Name);

            if (historicPriceExtract.HistoricPricesExtractResult == HistoricPricesExtractResult.SUCCESS)
            {
                //2. order prices
                IOrderedEnumerable<DailyPrice> orderedPrices = historicPriceExtract.DailyPrices.OrderByDescending(price => price.PriceDate);

                //3. get all time high
                DailyPrice allTimeHigh = orderedPrices.AllTimeHighestPriceByAdjustedHigh();

                //4. get all prices since all time high
                IEnumerable<DailyPrice> baseSinceAllTimeHigh = orderedPrices.Where(i => i.PriceDate >= allTimeHigh.PriceDate);

                //5. make sure there are no 0 prices
                if (!baseSinceAllTimeHigh.Any(i => i.AdjustedLow == 0))
                {
                    //6. get the low of the base
                    decimal baseLow = baseSinceAllTimeHigh.Min(i => i.AdjustedLow);

                    //7. the daily price for that low
                    DailyPrice baseLowPrice = baseSinceAllTimeHigh.First(i => i.AdjustedLow == baseLow);

                    //8. determine number of days in base
                    DailyPrice lastPrice = orderedPrices.ElementAt(0);

                    TimeSpan timeInBase = lastPrice.PriceDate - allTimeHigh.PriceDate;

                    int daysInBase = Convert.ToInt32(timeInBase.TotalDays);

                    //determine the base depth
                    decimal baseDepth = (allTimeHigh.AdjustedHigh - baseLow) / allTimeHigh.AdjustedHigh;

                }
            }
        }

        private void _SWIJustBrokenOutTestButton_Click(object sender, EventArgs e)
        {
            const string symbolName = "SWI";
            DateTime dateBrokeOut = new DateTime(2011, 10, 31);
            Symbol symbol = new Symbol { Name = symbolName };

            JustBrokenOutPriceAnalyser analyser = new JustBrokenOutPriceAnalyser();

            //1. get historical prices
            IHistoricPricesExtractor _YahooricesExtractor = new YahooHistoricPriceExtractor();

            //get price history
            HistoricPricesExtract historicPriceExtract = _YahooricesExtractor.ExtractHistoricPrices(
                DateTime.Now.AddYears(-20), DateTime.Today, symbol.Name);

            if (historicPriceExtract.HistoricPricesExtractResult == HistoricPricesExtractResult.SUCCESS)
            {
                //get prices upto breakout day
                IOrderedEnumerable<DailyPrice> brokenOutPrices = historicPriceExtract.DailyPrices
                    .Where(i => i.PriceDate <= dateBrokeOut)
                    .OrderByDescending(price => price.PriceDate);

                PriceAnalysisResult result = analyser.RunAnalysis(brokenOutPrices);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            /* test the just broken out analyser for 2 months
             * this will get every breakout */

            const string symbolName = "GMCR";
            Symbol symbol = new Symbol { Name = symbolName };

            JustBrokenOutPriceAnalyser analyser = new JustBrokenOutPriceAnalyser();

            //1. get historical prices
            IHistoricPricesExtractor _YahooricesExtractor = new YahooHistoricPriceExtractor();

            //get price history
            HistoricPricesExtract historicPriceExtract = _YahooricesExtractor.ExtractHistoricPrices(
                DateTime.Now.AddYears(-20), DateTime.Today, symbol.Name);

            if (historicPriceExtract.HistoricPricesExtractResult == HistoricPricesExtractResult.SUCCESS)
            {
                var prices = historicPriceExtract.DailyPrices.OrderBy(i => i.PriceDate);

                List<PriceAnalysisResult> results = new List<PriceAnalysisResult>();

                foreach (var item in prices)
                {
                    //get prices upto breakout day
                    IOrderedEnumerable<DailyPrice> brokenOutPrices = historicPriceExtract.DailyPrices
                        .Where(i => i.PriceDate <= item.PriceDate)
                        .OrderByDescending(price => price.PriceDate);

                    results.Add(analyser.RunAnalysis(brokenOutPrices));
                }

                var breakouts = results.Where(i => i.Succeeded);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            /*
             * 
             **/

            const string symbolName = "SWI";
            Symbol symbol = new Symbol { Name = symbolName };

            IPriceAnalyser analyser = new PriceWithinWindowPriceAnalyser();

            //1. get historical prices
            IHistoricPricesExtractor _YahooricesExtractor = new YahooHistoricPriceExtractor();

            //get price history
            HistoricPricesExtract historicPriceExtract = _YahooricesExtractor.ExtractHistoricPrices(
                DateTime.Now.AddYears(-20), DateTime.Today, symbol.Name);

            if (historicPriceExtract.HistoricPricesExtractResult == HistoricPricesExtractResult.SUCCESS)
            {
                var prices = historicPriceExtract.DailyPrices.OrderBy(i => i.PriceDate);

                List<PriceAnalysisResult> results = new List<PriceAnalysisResult>();

                foreach (var item in prices)
                {
                    //get prices upto breakout day
                    IOrderedEnumerable<DailyPrice> brokenOutPrices = historicPriceExtract.DailyPrices
                        .Where(i => i.PriceDate <= item.PriceDate)
                        .OrderByDescending(price => price.PriceDate);

                    results.Add(analyser.RunAnalysis(brokenOutPrices));
                }

                var breakouts = results.Where(i => i.Succeeded && i.DepthFromAllTimeHigh < 10);
            }
        }

        private void _FlatBaseTest_Click(object sender, EventArgs e)
        {
            FlatBasePriceAnalyser flatBaseAnalyser = new FlatBasePriceAnalyser();

            const string symbolName = "CRMT";
            Symbol symbol = new Symbol { Name = symbolName };  

            //1. get historical prices
            IHistoricPricesExtractor _YahooricesExtractor = new YahooHistoricPriceExtractor();

            //get price history
            HistoricPricesExtract historicPriceExtract = _YahooricesExtractor.ExtractHistoricPrices(
                DateTime.Now.AddYears(-20), DateTime.Today, symbol.Name);

            if (historicPriceExtract.HistoricPricesExtractResult == HistoricPricesExtractResult.SUCCESS)
            {
                var prices = historicPriceExtract.DailyPrices.OrderByDescending(i => i.PriceDate);

                flatBaseAnalyser.RunAnalysis(prices);
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            int counter = 0;

            //load symbols from database that have prices
            SymbolDataAccess symbolDataAccess = new SymbolDataAccess();
            DailyPriceDataAccess priceDataAccess = new DailyPriceDataAccess();

            List<Symbol> symbols = symbolDataAccess.GetListOfSymbolsThatHavePrices();            

            IPriceAnalyser flatBaseAnalyser = new FlatBasePriceAnalyser();
            List<PriceAnalysisResult> results = new List<PriceAnalysisResult>();
            PriceAnalysisResult result = null;
            IOrderedEnumerable<DailyPrice> orderedPrices = null;

            foreach (var symbol in symbols)
            {
                priceDataAccess.GetAllDailyPricesBySymbolId(symbol);

                orderedPrices = symbol.Prices.OrderByDescending(i => i.PriceDate);

                result = flatBaseAnalyser.RunAnalysis(orderedPrices);

                if (result.Succeeded)
                {
                    result.SymbolName = symbol.Name;
                    results.Add(result);
                }

                Debug.WriteLine(counter++);
            }

            results.ForEach(i => Debug.WriteLine(i.SymbolName));
        }

        private void _PostToWebserviceButton_Click(object sender, EventArgs e)
        {
            #region Web lookup variables

            HttpWebRequest webRequest;
            HttpWebResponse webResponse;
            string pageSource = string.Empty;
            CookieContainer cookieContainer = new CookieContainer();

            #endregion

            #region Get the composite ratings page

            Byte[] postData = Encoding.UTF8.GetBytes("<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body><GetScreenResult xmlns=\"http://www.williamoneil.com/webservices/taskcentric/genscreenerservice/v1\"><request xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><cacheID>-1</cacheID><userID>305410595179635</userID><screenID>86743</screenID><benchmarkScreenID>1</benchmarkScreenID><templateID>245620</templateID><pageNumbers>1,2</pageNumbers><pageSize>48</pageSize></request></GetScreenResult></s:Body></s:Envelope>");
            webRequest = (HttpWebRequest)(WebRequest.Create("http://webservices.marketsmith.com/WONServices/GenScreener/GenScreener.svc"));
            //webRequest.CookieContainer = cookieContainer;
            webRequest.Accept = "*//*";
            webRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5";
            webRequest.KeepAlive = true;
            webRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
            webRequest.Method = "POST";
            webRequest.ContentType = "text/xml; charset=utf-8";
            webRequest.ContentLength = postData.Length;

            //write the data to the stream
            Stream requestStream = webRequest.GetRequestStream();
            requestStream.Write(postData, 0, postData.Length);
            requestStream.Close();
            webResponse = (HttpWebResponse)webRequest.GetResponse();

            //get the response details
            using (StreamReader streamReader = new StreamReader(webResponse.GetResponseStream()))
            {
                //get the page response
                //pageSource = HttpUtility.HtmlEncode(streamReader.ReadToEnd());
                pageSource = (streamReader.ReadToEnd());

                //write the response to diagnostic file
                using (StreamWriter writer = new StreamWriter(new FileStream(string.Format("compositerating.xml"), FileMode.Create)))
                {
                    writer.Write(pageSource);
                }
            }

            webResponse.Close();

            #endregion 
        }

        private void _MarketsmithLoginButton_Click(object sender, EventArgs e)
        {
            CookieContainer cookieContainer = new CookieContainer();

            #region Access main site first

            var httpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.marketsmith.com");
            httpWebRequest.CookieContainer = cookieContainer;
            httpWebRequest.Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, #/#";
            httpWebRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5";
            httpWebRequest.KeepAlive = true;
            httpWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
            httpWebRequest.Method = "GET";
            httpWebRequest.ContentType = "application/x-www-form-urlencoded";
            var webResponse = (HttpWebResponse)httpWebRequest.GetResponse();

            #endregion

            #region Login

            httpWebRequest = (HttpWebRequest)WebRequest.Create("https://www.marketsmith.com/Secure/Login.aspx/Login");
            httpWebRequest.ContentType = "application/json; charset=utf-8";
            httpWebRequest.Method = "POST";
            httpWebRequest.CookieContainer = cookieContainer;

            using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
            {
                string json = "{\"username\":\"ssattin@gmail.com\",\"password\":\"dennis10\",\"rememberMe\":\"true\",\"trys\":\"1\",\"currentUrl\":\"http://www.marketsmith.com\"}";

                streamWriter.Write(json);
            }
            var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
            {
                var responseText = streamReader.ReadToEnd();
                //Now you have your response.
                //or false depending on information in the response               
            }

            #endregion

            #region Access main site again with cookies

            httpWebRequest = (HttpWebRequest)WebRequest.Create("http://www.marketsmith.com");
            httpWebRequest.CookieContainer = cookieContainer;
            httpWebRequest.Accept = "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-silverlight, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, #/#";
            httpWebRequest.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5";
            httpWebRequest.KeepAlive = true;
            httpWebRequest.Credentials = System.Net.CredentialCache.DefaultCredentials;
            httpWebRequest.Method = "GET";
            httpWebRequest.ContentType = "application/x-www-form-urlencoded";
            webResponse = (HttpWebResponse)httpWebRequest.GetResponse();

            #endregion            

            #region Get screen

            GenScreenerSvc sv = new GenScreenerSvc();
            sv.CookieContainer = cookieContainer;
            sv.Url = "http://webservices.marketsmith.com/WONServices/GenScreener/GenScreener.svc";
            sv.Timeout = -1;
            
            int PAGE_SIZE = 50;

            ScreenMessageIn s = new ScreenMessageIn();
            s.cacheID = -1;
            s.screenID = 86743;
            s.userID = 305410595179635;
            s.benchmarkScreenID = 1;
            s.templateID = 245620;
            s.pageNumbers = "1";
            s.pageSize = PAGE_SIZE;            

            var output = sv.GetScreenResult(s);

            var list = GetIBDRatingsFromMarketSmithOutput(output);

            foreach (var item in output.content.listPanelResult.columnHeaders)
            {
                Debug.WriteLine("Name: " + item.name);
            }

            //1. get the total number of rows
            int totalRows = output.content.listPanelResult.totalRows;

            decimal numberOfPages = Math.Ceiling((decimal)totalRows / (decimal)PAGE_SIZE);

            ////loop each page and get the output
            //for (int i = 1; i <= numberOfPages; i++)
            //{
            //    s.pageNumbers = numberOfPages.ToString();

            //    output = sv.GetScreenResult(s);
            //}

            #endregion 
        }

        private const int SYMBOL_COLUMNHEADER_INDEX = 2;
        private const int EPS_RATING_COLUMNHEADER_INDEX = 10;
        private const int RS_RATING_COLUMNHEADER_INDEX = 11;
        private const int GROUPRS_COLUMNHEADER_INDEX = 12;
        private const int SMRRATING_COLUMNHEADER_INDEX = 13;
        private const int ADRATING_COLUMNHEADER_INDEX = 14;
        private const int COMPOSITE_COLUMNHEADER_INDEX = 15;

        private List<IBDRatings> GetIBDRatingsFromMarketSmithOutput(ScreenMessageOut output)
        {
            List<IBDRatings> list = new List<IBDRatings>();
            IBDRatings rating = null;

            foreach (var item in output.content.listPanelResult.instrumentRows)
            {
                rating = new IBDRatings();
                list.Add(rating);

                if (item.valueList[SYMBOL_COLUMNHEADER_INDEX].value == null) continue;
                rating.Symbol = (string)item.valueList[SYMBOL_COLUMNHEADER_INDEX].value;

                if (item.valueList[EPS_RATING_COLUMNHEADER_INDEX].value == null) continue;
                rating.EPS = Convert.ToInt32(item.valueList[EPS_RATING_COLUMNHEADER_INDEX].value.ToString());

                if (item.valueList[RS_RATING_COLUMNHEADER_INDEX].value == null) continue;
                rating.RelativeStrength = Convert.ToInt32(item.valueList[RS_RATING_COLUMNHEADER_INDEX].value.ToString());

                if (item.valueList[GROUPRS_COLUMNHEADER_INDEX].value == null) continue;
                rating.GroupRSRating = (string)item.valueList[GROUPRS_COLUMNHEADER_INDEX].value;

                if (item.valueList[SMRRATING_COLUMNHEADER_INDEX].value == null) continue;
                rating.SMR = (string)item.valueList[SMRRATING_COLUMNHEADER_INDEX].value;

                if (item.valueList[ADRATING_COLUMNHEADER_INDEX].value == null) continue;
                rating.AccDist = (string)item.valueList[ADRATING_COLUMNHEADER_INDEX].value;

                if (item.valueList[COMPOSITE_COLUMNHEADER_INDEX].value == null) continue;
                rating.IBDComposite = Convert.ToInt32(item.valueList[COMPOSITE_COLUMNHEADER_INDEX].value.ToString());
            }

            return list;
        }



        private string GetStringValue(InstrumentRowType1 input, int index)
        {
            string defaultValue = "N/A";



            return defaultValue;
        }

        private void _MarketSmithCompositeRatingsButton_Click(object sender, EventArgs e)
        {
            MarketSmithIBDCompositeExtractor extractor = new MarketSmithIBDCompositeExtractor();
            var list = extractor.GetIBDRatingsFromMarketSmith();
            Debug.WriteLine("List total: " + list.Item2.Count);
            Debug.WriteLine("Stock Type total: " + list.Item2.Count(i => i.StockType == "Stock"));

        }

        private void _ThreeWeeksTightTestButton_Click(object sender, EventArgs e)
        {
            //get prices for aapl

            HistoricPricesExtract result = _YahooricesExtractor.GetHistoricPrices("AAPL");

            IPriceAnalyser threeWeeksTight = new ThreeWeeksTightPriceAnalyser();

            var prices = result.DailyPrices.OrderByDescending(i => i.PriceDate);

            threeWeeksTight.RunAnalysis(prices);
        }

        private void _MatchingSymbolListButton_Click(object sender, EventArgs e)
        {
            //load telechart list
            string teleChartListFilepath = "C:\\Data\\telechartlist.txt";
            List<string> teleChartList = new List<string>();
            using (StreamReader sr = new StreamReader(teleChartListFilepath))
            {
                teleChartList.AddRange(sr.ReadToEnd().Replace("\r\n"," ").Split(new char[] { ' ' }).ToList());
            }

            //load eod data list
            string ibdListFilepath = "C:\\Data\\ibdlist.txt";

            List<string> ibdList = new List<string>();

            using (StreamReader sr = new StreamReader(ibdListFilepath))
            {
                ibdList.AddRange(sr.ReadToEnd().Replace("\r\n", " ").Split(new char[] { ' ' }).ToList());
            }            

            var notInEodList = ibdList.Where(x => !teleChartList.Any(x1 => x1 == x));
            var notInTelechartList = teleChartList.Where(x => !ibdList.Any(x1 => x1 == x));

            Debug.WriteLine("Not in eodData list...");

            foreach (var item in notInEodList)
            {
                System.Diagnostics.Debug.WriteLine(item);
            }

            Debug.WriteLine("Not in telechart list...");

            foreach (var item in notInTelechartList)
            {
                System.Diagnostics.Debug.WriteLine(item);
            }
        }

        private void _SaveRatingsListButton_Click(object sender, EventArgs e)
        {
            IBDRatingDatabaseUpdater ibdRatingDatabaseUpdater = new IBDRatingDatabaseUpdater();
            ibdRatingDatabaseUpdater.Run();
        }

        private void _PriceHistoryDatabaseUpdateButton_Click(object sender, EventArgs e)
        {
            var ratingsText = string.Empty;
            //load ratings list
            using (StreamReader reader = new StreamReader("C:\\Data\\IBD\\Ratings\\29062012.csv"))
            {
                ratingsText = reader.ReadToEnd();
            }

            var lines = ratingsText.Split(new string[] { "\r\n" },StringSplitOptions.RemoveEmptyEntries).ToList();
            
            List<string> symbols = new List<string>();

            string symbol = string.Empty;
            bool isETF = false;

            foreach (var line in lines.Skip(1))
            {
                symbol = line.Split(new char[] { ',' })[0];
                isETF = Convert.ToBoolean(line.Split(new char[] { ',' })[9]);
                if (!isETF) symbols.Add(symbol);
            }

           
        }

        private void _PriceHistoryDatabaseLoadButton_Click(object sender, EventArgs e)
        {
            // save the price database
            using (IObjectContainer database = Db4oEmbedded.OpenFile(GeCreateIEmbeddedConfiguration(),
                ApplicationConfiguation.ObjectDatabaseSRootDirectory + ObjectDatabaseFilenames.PRICE_HISTORY_DATABASE))
            {
                //get or create PriceHistoryContainer
                List<PriceHistoryDatabase> priceHistoryDatabases = database.Query<PriceHistoryDatabase>().ToList();

                //should only be 1 price history container
                PriceHistoryDatabase priceHistoryDatabase = priceHistoryDatabases[0];
            }
        }

        private IEmbeddedConfiguration GeCreateIEmbeddedConfiguration()
        {
            IEmbeddedConfiguration config = Db4oEmbedded.NewConfiguration();
            //config.Common.ActivationDepth = 1;
            config.File.BlockSize = 8;
            //config.Common.ObjectClass(typeof(PriceHistoryContainer)).CascadeOnUpdate(true);
            //config.Common.ObjectClass(typeof(DailyPrice)).CascadeOnUpdate(true);
            //config.Common.ObjectClass(typeof(Symbol)).CascadeOnUpdate(true);

            return config;
        }

        private IEmbeddedConfiguration GeSingleActivationCreateIEmbeddedConfiguration()
        {
            IEmbeddedConfiguration config = Db4oEmbedded.NewConfiguration();
            config.Common.ActivationDepth = 1;
            config.File.BlockSize = 8;

            return config;
        }

        private void _ReformattedBadSymbolTestButton_Click(object sender, EventArgs e)
        {
            PriceHistoryDatabaseUpdater priceUpdater = new PriceHistoryDatabaseUpdater();

            IBDRatingDatabaseUpdater ratingsUpdater = new IBDRatingDatabaseUpdater();
            ratingsUpdater.LoadFromFile();

            //priceUpdater.Run(ratingsUpdater.IBDRatingsList);            
        }

        private void button4_Click(object sender, EventArgs e)
        {
            //PriceHistoryDatabaseUpdater priceUpdater = new PriceHistoryDatabaseUpdater();
            //priceUpdater.LoadFromFile();

            PriceHistoryContainerUpdater container = new PriceHistoryContainerUpdater();
            container.Run();            
        }

        private void button5_Click(object sender, EventArgs e)
        {
            using (IObjectContainer database = Db4oEmbedded.OpenFile(GeCreateIEmbeddedConfiguration(),
                ApplicationConfiguation.ObjectDatabaseSRootDirectory + ObjectDatabaseFilenames.PRICE_HISTORY))
            {
                PriceHistoryContainer priceHistoryContainer = null;

                //get or create PriceHistoryContainer
                List<PriceHistoryContainer> priceHistoryContainers = database.Query<PriceHistoryContainer>().ToList();

                //PriceHistoryContainer doesnt exist so create it
                if (priceHistoryContainers == null || priceHistoryContainers.Count() == 0)
                {
                    priceHistoryContainer = new PriceHistoryContainer();
                }
                else
                {
                    //should only be 1 price history container
                    priceHistoryContainer = priceHistoryContainers[0];
                }

                //get symbol list into memory
                Random random = new Random();
                int number = 0;
                foreach (var item in priceHistoryContainer.Symbols)
                {
                    foreach (var price in item.Prices)
                    {
                        number = random.Next(10, 1000000);

                        price.AdjustedClose = number;
                        price.Close = number - 1;
                        price.High = number + 2;
                        price.Low = number - 2;
                        price.Open = number + 1;
                        price.Volume = number + 10;
                    }

                    _Log.DebugFormat("Current item first price: {0}", item.Prices[0].AdjustedClose);
                    _Log.DebugFormat("First item first price: {0}", priceHistoryContainer.Symbols[0].Prices[0].AdjustedClose);                    
                }
            }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            //get latest IBD ratings
            IBDRatingDatabaseUpdater ratingsUpdater = new IBDRatingDatabaseUpdater();
            ratingsUpdater.LoadFromFile();

            //generate filename
            string databaseFileName = ApplicationConfiguation.ObjectDatabaseSRootDirectory + ObjectDatabaseFilenames.PRICE_HISTORY_DATABASE;

            //remove if already exists, want latest only
            if (File.Exists(databaseFileName))
            {
                File.Delete(databaseFileName);
            }

            // save the price database
            using (IObjectContainer database = Db4oEmbedded.OpenFile(GeCreateIEmbeddedConfiguration(), databaseFileName))
            {
                PriceHistoryDatabase priceHistoryDatabase = new PriceHistoryDatabase();
                database.Store(priceHistoryDatabase);
            }

            // save the price database
            using (IObjectContainer database = Db4oEmbedded.OpenFile(GeSingleActivationCreateIEmbeddedConfiguration(),
                databaseFileName))
            {
                PriceHistoryDatabase priceHistoryDatabase = null;

                var priceHistoryDatabases = database.Query<PriceHistoryDatabase>();

                if (priceHistoryDatabases == null || priceHistoryDatabases.Count == 0)
                {
                    throw new Exception(string.Format("Could not load from file location {0}", databaseFileName));
                }

                priceHistoryDatabase = priceHistoryDatabases[0];

                //activate the price items into memory
                database.Activate(priceHistoryDatabase.SymbolPriceHistoryItems, 2);

                ////generate list
                //foreach (var item in ratingsUpdater.IBDRatingsList)
                //{
                //    priceHistoryDatabase.SymbolPriceHistoryItems.Add(new SymbolPriceHistoryItem()
                //    {
                //        IBDRatings = item,
                //        Symbol = item.Symbol
                //    });                   
                //}

                //database.Store(priceHistoryDatabase.SymbolPriceHistoryItems);
            }

            // generate the prices
            using (IObjectContainer database = Db4oEmbedded.OpenFile(GeSingleActivationCreateIEmbeddedConfiguration(),
                databaseFileName))
            {
                PriceHistoryDatabase priceHistoryDatabase = null;

                var priceHistoryDatabases = database.Query<PriceHistoryDatabase>();

                if (priceHistoryDatabases == null || priceHistoryDatabases.Count == 0)
                {
                    throw new Exception(string.Format("Could not load from file location {0}", databaseFileName));
                }

                priceHistoryDatabase = priceHistoryDatabases[0];

                //activate the price items into memory
                database.Activate(priceHistoryDatabase.SymbolPriceHistoryItems, 1);

                Random random = new Random();
                int numberOfPrices = 0;
                SymbolPriceHistoryItem item = null;

                for (int i = 0; i < priceHistoryDatabase.SymbolPriceHistoryItems.Count; i++)
			    {
                    item = priceHistoryDatabase.SymbolPriceHistoryItems[i];

                    //bring list into memory
                    database.Activate(item, 2);

                    //random number of prices
                    numberOfPrices = random.Next(10, 3500);                    

                    for (int j = 0; j < numberOfPrices; j++)
                    {
                        item.DailyPrices.Add(new DailyPrice());
                    }

                    //store prices
                    database.Store(item.DailyPrices);

                    //clean up references otherwise flooded with prices                  
                    item.DailyPrices.Clear();
                    item.DailyPrices = null;
                    item = null;
                    database.Deactivate(item, 5);
                    //GC.Collect();

                    _Log.InfoFormat("{0:0.0%} completed", (double)i / priceHistoryDatabase.SymbolPriceHistoryItems.Count); 
                }
            }
        }

        private void button7_Click(object sender, EventArgs e)
        {
            //load IBD Ratings
            IBDRatingDatabaseUpdater ibdRatingsUpdater = new IBDRatingDatabaseUpdater();
            ibdRatingsUpdater.LoadFromFile();

            //truncate price table
            DailyPriceDataAccess.TruncateDailyPriceTable();

            IHistoricPricesExtractor yahooPricesExtractor = new YahooHistoricPriceExtractor();
            List<DailyPrice> prices = null;
            const int YEARS_BACK_TO_DOWNLOAD = 30;
            IBDRatings item = null;

            DataTable pricesTable = new DataTable("DailyPrice");
            pricesTable.Columns.Add("Open", typeof(decimal));
            pricesTable.Columns.Add("High", typeof(decimal));
            pricesTable.Columns.Add("Low", typeof(decimal));
            pricesTable.Columns.Add("Close", typeof(decimal));
            pricesTable.Columns.Add("Volume", typeof(long));
            pricesTable.Columns.Add("Symbol", typeof(string));
            pricesTable.Columns.Add("PriceDate", typeof(DateTime));
            pricesTable.Columns.Add("AdjustedClose", typeof(decimal));
            pricesTable.Columns.Add("AdjustedOpen", typeof(decimal));
            pricesTable.Columns.Add("AdjustedHigh", typeof(decimal));
            pricesTable.Columns.Add("AdjustedLow", typeof(decimal));

            ////download price history
            //for (int i = 0; i < ibdRatingsUpdater.IBDRatingsList.Count; i++)
            //{
            //    item = ibdRatingsUpdater.IBDRatingsList[i];

            //    pricesTable.Rows.Clear();

            //    _Log.DebugFormat("Downloading prices for {0}", item.Symbol);

            //    prices = yahooPricesExtractor.GetHistoricPrices(
            //            DateTime.Now.AddYears(-YEARS_BACK_TO_DOWNLOAD), DateTime.Today, item.Symbol);

            //    //are there any prices
            //    if (prices == null)
            //    {
            //        _Log.WarnFormat("Problem getting prices for {0}", item.Symbol);
            //    }
            //    else
            //    {
            //        _Log.DebugFormat("Adding {0} prices", prices.Count);

            //        SqlBulkCopy bulkCopy = new SqlBulkCopy(ApplicationConfiguation.DatabaseConnectionString,
            //            SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.UseInternalTransaction);
            //        bulkCopy.DestinationTableName = "dbo.DailyPrice";

            //        foreach (var price in prices)
            //        {
            //            var row = pricesTable.NewRow();
            //            row["Open"] = price.Open;
            //            row["High"] = price.High;
            //            row["Low"] = price.Low;
            //            row["Close"] = price.Close;
            //            row["Volume"] = price.Volume;
            //            row["Symbol"] = item.Symbol;
            //            row["PriceDate"] = price.PriceDate;
            //            row["AdjustedClose"] = price.AdjustedClose;
            //            row["AdjustedOpen"] = price.AdjustedOpen;
            //            row["AdjustedHigh"] = price.AdjustedHigh;
            //            row["AdjustedLow"] = price.AdjustedLow;
            //            pricesTable.Rows.Add(row);
            //        }

            //        bulkCopy.WriteToServer(pricesTable);

            //        _Log.DebugFormat("Added prices");
            //    }

            //    _Log.InfoFormat("{0:0.0%} completed", (double)i / ibdRatingsUpdater.IBDRatingsList.Count);
            //}
        }

        private void button8_Click(object sender, EventArgs e)
        {
            var extractor = new YahooHistoricPriceExtractor();
            var prices = extractor.GetHistoricPrices(DateTime.Today.AddYears(-30), DateTime.Today, "AAPL");

            DailyPricesHistoryDatabaseUpdater dpu = new DailyPricesHistoryDatabaseUpdater();
            dpu.Run(new List<string>() { "AAPL", "MSFT", "CTRX" });
        }

        private void button9_Click(object sender, EventArgs e)
        {
            /* ((((C - C63) / C63) * .4) + (((C - C126) / C126) * .2) + (((C - C189) / C189) * .2) + (((C - C252) / C252) * .2)) * 100 */

            var prices = DailyPriceDataAccess.GetAllDailyPricesBySymbol("AAPL");

            var c = prices[0].AdjustedClose;
            var c1 = prices[63].AdjustedClose;
            var c2 = prices[126].AdjustedClose;
            var c3 = prices[189].AdjustedClose;
            var c4 = prices[252].AdjustedClose;

            var r1 = (((c - c1) / c1) * .4m);
            var r2 = (((c - c2) / c2) * .2m);
            var r3 = (((c - c3) / c3) * .2m);
            var r4 = (((c - c4) / c4) * .2m);

            var t1 = r1 + r2 + r3 + r4;

            var result = t1 * 100;
        }

        private void button10_Click(object sender, EventArgs e)
        {
            //1 get all symbols
            var symbols = SymbolDataAccess.GetAllSymbols();
            Symbol symbol = null;

            Stopwatch s = new Stopwatch();
            s.Start();

            for (int i = 0; i < symbols.Count; i++)
            {
                symbol = symbols[i];

                var prices = DailyPriceDataAccess.GetAllDailyPricesBySymbol(symbol.Name);

                var orderedPrices = prices.OrderByDescending(p => p.PriceDate);

                Debug.WriteLine(string.Format("{0}: {1}", i, prices.Count));
            }

            Debug.WriteLine(s.Elapsed.TotalSeconds);
            s.Stop();
        }

        private void button11_Click(object sender, EventArgs e)
        {
            RelativeStrengthPriceDatabaseAnalyser relativeStrengthPriceDatabaseAnalyser = 
                new RelativeStrengthPriceDatabaseAnalyser();

            relativeStrengthPriceDatabaseAnalyser.Run();
        }

        private void button12_Click(object sender, EventArgs e)
        {
            int RestartTimeout = 10000;
            ServiceController service = new ServiceController();
            service.ServiceName = "MSSQLSERVER";            
            
            if (service.Status != ServiceControllerStatus.Stopped)
            {
                service.Stop();

                int i = 0;
                while (service.Status != ServiceControllerStatus.Stopped)
                {
                    service.Refresh();
                    Thread.Sleep(100);
                    i++;

                    if (i >= RestartTimeout / 100)
                    {
                        MessageBox.Show(@"Restart Stop Timeout Exceeded");
                    }
                }
            }

            service.Start();
        }

        private void button13_Click(object sender, EventArgs e)
        {
            var analyser = new WithinSpecifiedRangeOfAllTimeHighPriceDatabaseAnalyser();
            var symbols = new List<Symbol>();
            symbols.Add(new Symbol() { Name = "ACIW" });
            symbols.Add(new Symbol() { Name = "ANCX" });
            symbols.Add(new Symbol() { Name = "AAPL" });
            symbols.Add(new Symbol() { Name = "BGS" });

            foreach (var item in symbols)
            {
                var prices = DailyPriceDataAccess.GetAllDailyPricesBySymbol(item.Name);

                analyser.AnalysePrices(prices);
            }
        }

        private void button14_Click(object sender, EventArgs e)
        {
            /* average true range */            

            var prices = DailyPriceDataAccess.GetAllDailyPricesBySymbol("NSM");

            var atrCalculator = new ExponentialMovingAverageTrueRangeClosePriceDayIndicator(14, DayIndicatorNames.CLOSE_EMATR14);

            atrCalculator.ApplyIndicator(prices);
        }

        private void button15_Click(object sender, EventArgs e)
        {
            var prices = DailyPriceDataAccess.GetAllDailyPricesBySymbol("NSM");                        
        }

        private void button16_Click(object sender, EventArgs e)
        {
          
        }

        private void button17_Click(object sender, EventArgs e)
        {
            var symbols = SymbolDataAccess.GetAllSymbols();

            Symbol currentSymbol = null;
            List<DailyPrice> prices = null;            
            var ath = new AllTimeHighBreakoutPriceDatabaseAnalyser();
            var jbo = new JustBrokenOutPriceAnalyser();
            var paResults = new List<PriceAnalysisResult>();
            PriceAnalysisResult paResult = null;
            var pdbResults = new List<PriceDatabaseAnalyserResult>();
            PriceDatabaseAnalyserResult pdResult = null;

            Debug.WriteLine("Starting...");

            for (int i = 0; i < symbols.Count; i++)
            {
                currentSymbol = symbols[i];

                prices = DailyPriceDataAccess.GetAllDailyPricesBySymbol(currentSymbol.Name);

                pdResult = ath.AnalysePrices(prices);

                if (pdResult.Succeeded) pdbResults.Add(pdResult);                

                paResult = jbo.RunAnalysis(prices.OrderByDescending(p => p.PriceDate));

                if (paResult.Succeeded) paResults.Add(paResult);

                Debug.WriteLine(string.Format("{0}/{1}", i, symbols.Count));
            }
        }

        private void button18_Click(object sender, EventArgs e)
        {
            //get prices for NASDAQ
            var extractor = new YahooCsvHistoricPricesExtractor();

            var prices = extractor.GetHistoricPrices(@"C:\SVNHome\trunk\test\testnasdaq.csv");
            
            var originalPrice = prices[0];
            var originalPriceClose = originalPrice.AdjustedClose;
            var maxPercentChange = 0M;

            for (int i = 1; i < prices.Count; i++)
            {
                var currentPrice = prices[i];
                var currentClose = currentPrice.AdjustedClose;

                var percentChangeFromOriginal = ((currentClose - originalPriceClose)/originalPriceClose)*100;

                //is this the new ceiling?
                if (percentChangeFromOriginal > maxPercentChange)
                {
                    //yes so set
                    maxPercentChange = percentChangeFromOriginal;
                }                

                var drawDown = ((maxPercentChange - percentChangeFromOriginal) / maxPercentChange) * 100;

                Debug.WriteLine(string.Format("{0},{1},{2},{3}",currentPrice.PriceDate.ToString("dd/MM/yyyy"),percentChangeFromOriginal,maxPercentChange,Math.Round(drawDown,2)));
            }
        }

        /// <summary>
        /// Traverse the list of prices until the Max Drawdown limit is reached i.e. what move can we find until draw down level breached
        /// </summary>
        /// <param name="maxDrawDown"></param>
        /// <param name="prices"></param>
        /// <returns></returns>
        private decimal TraverseUntilMaxDrawdownReached(decimal maxDrawDown, List<DailyPrice> prices)
        {
            var percentChangeCeiling = 0m;
            var originalPrice = prices[0];
            var originalPriceClose = originalPrice.AdjustedClose;

            for (int i = 1; i < prices.Count; i++)
            {
                var currentPrice = prices[i];
                var currentClose = currentPrice.AdjustedClose;

                var percentChangeFromOriginal = ((currentClose - originalPriceClose) / originalPriceClose) * 100;

                //is this the new ceiling?
                if (percentChangeFromOriginal > percentChangeCeiling)
                {
                    //yes so set
                    percentChangeCeiling = percentChangeFromOriginal;
                }

                var drawDown = ((percentChangeCeiling - percentChangeFromOriginal) / percentChangeCeiling) * 100;

                if (drawDown > maxDrawDown)
                {
                    break;
                }
            }

            return percentChangeCeiling;
        }

        private void button19_Click(object sender, EventArgs e)
        {
            //get prices for NASDAQ
            var extractor = new YahooCsvHistoricPricesExtractor();

            var prices = extractor.GetHistoricPrices(@"C:\SVNHome\trunk\test\testnasdaq.csv");

            prices = new List<DailyPrice>();
            prices.Add(new DailyPrice() { AdjustedClose = 20 });
            prices.Add(new DailyPrice() { AdjustedClose = 19 });
            prices.Add(new DailyPrice() { AdjustedClose = 18 });
            prices.Add(new DailyPrice() { AdjustedClose = 17 });
            prices.Add(new DailyPrice() { AdjustedClose = 20 });
            prices.Add(new DailyPrice() { AdjustedClose = 21 });//dd fin
            prices.Add(new DailyPrice() { AdjustedClose = 22 });
            prices.Add(new DailyPrice() { AdjustedClose = 23 });
            prices.Add(new DailyPrice() { AdjustedClose = 23 });
            prices.Add(new DailyPrice() { AdjustedClose = 24 });
            prices.Add(new DailyPrice() { AdjustedClose = 25 });
            prices.Add(new DailyPrice() { AdjustedClose = 19 });//up fin
            prices.Add(new DailyPrice() { AdjustedClose = 21 });
            prices.Add(new DailyPrice() { AdjustedClose = 24 });
            prices.Add(new DailyPrice() { AdjustedClose = 25 });
            prices.Add(new DailyPrice() { AdjustedClose = 26 });//dd finished
            prices.Add(new DailyPrice() { AdjustedClose = 27 });

            decimal previousHighPrice = 0;
            decimal drawDownLowPrice = 0;
            int daysInCurrentMove = 0;
            bool isInDrawdown = true;            
            DailyPrice lastMoveStartPrice = null;
            DailyPrice dailyPrice = null;           

            for (int i = 0; i < prices.Count; i++ )
            {
                dailyPrice = prices[i];

                if (i == 0)
                {
                    lastMoveStartPrice = dailyPrice;                
                }
                else if (i == 1)
                {
                    if (dailyPrice.AdjustedClose < lastMoveStartPrice.AdjustedClose)
                    {
                        isInDrawdown = true;
                        drawDownLowPrice = dailyPrice.AdjustedClose;
                        previousHighPrice = lastMoveStartPrice.AdjustedClose;
                    }
                    else
                    {
                        isInDrawdown = false;
                        previousHighPrice = dailyPrice.AdjustedClose;
                        drawDownLowPrice = lastMoveStartPrice.AdjustedClose;
                    }

                    daysInCurrentMove++;
                }
                else
                {
                    if (isInDrawdown)
                    {
                        /* DRAW DOWN */

                        if (dailyPrice.AdjustedClose == previousHighPrice)
                        {
                            //no change, just add a day
                            daysInCurrentMove++;
                        }
                        else if (dailyPrice.AdjustedClose > previousHighPrice)
                        {
                            //new uptrend?
                            var drawDown = ((previousHighPrice - drawDownLowPrice) / previousHighPrice) * 100;

                            Debug.WriteLine(string.Format("Previous draw down finished with {0}% move for {1} days", Math.Round(drawDown, 2), daysInCurrentMove));

                            isInDrawdown = false;
                            daysInCurrentMove = 1;
                            lastMoveStartPrice = dailyPrice;
                            drawDownLowPrice = previousHighPrice;
                            previousHighPrice = dailyPrice.AdjustedClose;

                        }
                        else if (dailyPrice.AdjustedClose < drawDownLowPrice)
                        {
                            //new low price?
                            drawDownLowPrice = dailyPrice.AdjustedClose;
                            daysInCurrentMove++;
                        }
                        else
                        {
                            daysInCurrentMove++;
                        }
                    }
                    else
                    {
                        /* UP-MOVE */

                        if (dailyPrice.AdjustedClose == previousHighPrice)
                        {
                            //no change, just add a day
                            daysInCurrentMove++;
                        }
                        else if (dailyPrice.AdjustedClose > previousHighPrice)
                        {
                            //higher uptrend?
                            previousHighPrice = dailyPrice.AdjustedClose;
                            daysInCurrentMove++;                            
                        }
                        else if (dailyPrice.AdjustedClose < previousHighPrice)
                        {
                            //new draw down - log previous up move
                            var upMove = ((previousHighPrice - drawDownLowPrice) / drawDownLowPrice) * 100;

                            Debug.WriteLine(string.Format("Previous Up move finished with {0}% move for {1} days", Math.Round(upMove, 2), daysInCurrentMove));

                            //setup for new draw down
                            lastMoveStartPrice = dailyPrice;
                            isInDrawdown = true;
                            drawDownLowPrice = dailyPrice.AdjustedClose;
                            daysInCurrentMove = 1;
                        }
                        else
                        {
                            daysInCurrentMove++;
                        }
                    }                   
                }
            }

            if (isInDrawdown)
            {
                var drawDown = ((previousHighPrice - drawDownLowPrice) / previousHighPrice) * 100;

                Debug.WriteLine(string.Format("Currently in a draw down of {0}% for {1} days", Math.Round(drawDown, 2), daysInCurrentMove));
            }
            else
            {
                //new draw down - log previous up move
                var upMove = ((previousHighPrice - drawDownLowPrice) / drawDownLowPrice) * 100;

                Debug.WriteLine(string.Format("Currently in a {0}% move for {1} days", Math.Round(upMove, 2), daysInCurrentMove));
            }
        }

        private void button20_Click(object sender, EventArgs e)
        {
            var prices = DailyPriceDataAccess.GetAllDailyPricesBySymbol("AAPL");

            var nhb = new NewHighBreakoutAndDrawdownPerformanceMoveAnalyser();

            var moves = nhb.AnalysePrices(prices);

            foreach (var item in moves)
            {
                if (item.IsDrawDown)
                {
                    Debug.WriteLine(string.Format("Draw down of {0}% from {1} lasted for {2} days", 
                        Math.Round(item.MoveAmount, 2), item.StartDate.ToString("dd/MM/yyyy"), item.DaysOfMove));
                }
                else
                {
                    Debug.WriteLine(string.Format("Up move of {0}% from {1} lasted for {2} days",
                        Math.Round(item.MoveAmount, 2), item.StartDate.ToString("dd/MM/yyyy"), item.DaysOfMove));
                }
            }

            var upMoves = moves.Where(m => !m.IsDrawDown);

            foreach (var item in upMoves.OrderByDescending(m => m.MoveAmount))
            {
                Debug.WriteLine(string.Format("{0}% from {1} lasted for {2} days",
                        Math.Round(item.MoveAmount, 2), item.StartDate.ToString("dd/MM/yyyy"), item.DaysOfMove));
            }
        }

        private void button21_Click(object sender, EventArgs e)
        {
            //get prices for NASDAQ
            var extractor = new YahooCsvHistoricPricesExtractor();

            var prices = extractor.GetHistoricPrices(@"C:\Data\stockfinder\trunk\nasdaq.csv");

            IOrderedEnumerable<DailyPrice> orderedPrices = prices.OrderBy(p => p.PriceDate);
            DailyPrice currentPrice = null;
            int numberToSkip = 0;
            const int NUMBEROFPRICES = 5;

            IEnumerable<DailyPrice> skippedPrices = null;
            IEnumerable<DailyPrice> takenPrices = null;

            //start from 50
            for (int i = (NUMBEROFPRICES - 1); i < orderedPrices.Count(); i++)
            {
                currentPrice = orderedPrices.ElementAt(i);

                numberToSkip = (i + 1) - NUMBEROFPRICES;

                skippedPrices = orderedPrices.Skip(numberToSkip);

                takenPrices = skippedPrices.Take(NUMBEROFPRICES);

                //currentPrice.TradingRangeVolatility5 = takenPrices.Average(p => ((p.AdjustedHigh - p.AdjustedLow) / p.AdjustedLow) * 100);
            }
        }

        private void button23_Click(object sender, EventArgs e)
        {
            /* breaches price point in realtime */

            var priceBreachContenders = PriceBreachDataAccess.GetAllPriceBreachContenders();

            var timer = new System.Threading.Timer(PriceBreachCallBack, priceBreachContenders, 1000, 15 * 60 * 1000); //every 15 mins
        }

        static void PriceBreachCallBack(object state)
        {
            //US market opens @ 2:30pm
            var marketOpenDateTime = DateTime.Today.AddHours(14).AddMinutes(30);
            const int TOTAL_MARKET_MINUTES = 390;

            var timeSinceMarketOpen = DateTime.Now - marketOpenDateTime;

            var minutesSinceMarketOpen = Math.Round(timeSinceMarketOpen.TotalMinutes, 0);
           
            var percentageTimeSinceMarketOpen = (minutesSinceMarketOpen / TOTAL_MARKET_MINUTES) * 100;

            //do something
            var priceBreachContenders = state as List<PriceBreachContender>;

            if (priceBreachContenders != null)
            {
                foreach (var priceBreachContender in priceBreachContenders)
                {
                    //download realtime price
                    using (var wc = new ProxiedWebClient())
                    {
                        string url = string.Format("http://download.finance.yahoo.com/d/quotes.csv?s={0}&f=l1va2&e=.csv", priceBreachContender.Symbol);

                        var realTimeQuoteInfo = wc.DownloadString(url);
                        realTimeQuoteInfo = realTimeQuoteInfo.Replace(Environment.NewLine, string.Empty);

                        var cells = realTimeQuoteInfo.Split(new[] { ',' });

                        var price = Convert.ToDecimal(cells[0]);
                        var volume = Convert.ToInt64(cells[1]);
                        var averageVolume = Convert.ToInt64(cells[2]);

                        if (price > priceBreachContender.Price)
                        {
                            /* price breach! */

                            //within market open?
                            if (percentageTimeSinceMarketOpen > 0 && percentageTimeSinceMarketOpen < 100)
                            {
                                //get par volume for this time of day
                                var parVolume = (percentageTimeSinceMarketOpen / 100) * averageVolume;

                                //get relative volume change
                                var relativeVolume = ((volume - parVolume) / parVolume) * 100;

                                //email result
                                var client = new SmtpClient("smtp.gmail.com", 587) {EnableSsl = true};
                                var from = new MailAddress("ssattin@gmail.com", "Simon Sattin");
                                var message = new MailMessage(from, from)
                                                  {
                                                      Subject =
                                                          string.Format("Price Breached by {0}",
                                                                        priceBreachContender.Symbol)
                                                  };
                                var myCreds = new NetworkCredential("ssattin@gmail.com", "bergkamp_10", "");
                                client.Credentials = myCreds;

                                var sb = new StringBuilder();
                                sb.AppendLine(string.Format("{0} has breached price of {1} (last trade: {2}) with {3}% relative volume",
                                    priceBreachContender.Symbol, priceBreachContender.Price, price, relativeVolume));
                                sb.AppendLine(priceBreachContender.Notes);

                                message.Body = sb.ToString();

                                client.Send(message);
                            }
                        }
                    }
                }
            }
        }

        private void button24_Click(object sender, EventArgs e)
        {
            var symbolsToWatchForHighRelativeVolume = new List<string>();
            symbolsToWatchForHighRelativeVolume.Add("HCII");
            symbolsToWatchForHighRelativeVolume.Add("GNC");
            symbolsToWatchForHighRelativeVolume.Add("HPY");
            symbolsToWatchForHighRelativeVolume.Add("GNRC");

            var timer = new System.Threading.Timer(HighRelativeVolumeCallBack, symbolsToWatchForHighRelativeVolume, 1000, 15 * 60 * 1000); //every 15 mins
        }

        static void HighRelativeVolumeCallBack(object state)
        {
            //US market opens @ 2:30pm but 15 min delayed
            var marketOpenDateTime = DateTime.Today.AddHours(14).AddMinutes(45);
            const int TOTAL_MARKET_MINUTES = 390;

            var timeSinceMarketOpen = DateTime.Now - marketOpenDateTime;

            var minutesSinceMarketOpen = Math.Round(timeSinceMarketOpen.TotalMinutes, 0);

            var percentageTimeSinceMarketOpen = (minutesSinceMarketOpen / TOTAL_MARKET_MINUTES) * 100;

            var sb = new StringBuilder();
            bool anyUpRelativeVolume = false;

            var symbolsToWatchForHighRelativeVolume = state as List<string>;

            if (symbolsToWatchForHighRelativeVolume != null)
            {
                foreach (var symbol in symbolsToWatchForHighRelativeVolume)
                {
                    //download realtime price
                    using (var wc = new ProxiedWebClient())
                    {
                        try
                        {
                            string url = string.Format("http://download.finance.yahoo.com/d/quotes.csv?s={0}&f=l1va2p2&e=.csv", symbol);

                            var realTimeQuoteInfo = wc.DownloadString(url);
                            realTimeQuoteInfo = realTimeQuoteInfo.Replace(Environment.NewLine, string.Empty);

                            var cells = realTimeQuoteInfo.Split(new[] { ',' });

                            var price = Convert.ToDecimal(cells[0]);
                            var volume = Convert.ToInt64(cells[1]);
                            var averageVolume = Convert.ToInt64(cells[2]);
                            var priceChange = Convert.ToDecimal(cells[3].Replace("%", "").Replace("+", "").Replace("\"", ""));

                            //get par volume for this time of day
                            var parVolume = (percentageTimeSinceMarketOpen / 100) * averageVolume;

                            //get relative volume change
                            var relativeVolume = ((volume - parVolume) / parVolume) * 100;

                            //up for the day on more than 30% higher volume
                            if (relativeVolume > 30 && priceChange > 0)
                            {
                                sb.AppendLine(string.Format("{0} currently trading {1}% higher volume with change of {2}% for the day",
                                                            symbol, relativeVolume, priceChange));

                                anyUpRelativeVolume = true;
                            }
                        }
                        catch (Exception exception)
                        {
                            string error = exception.ToString();                                
                        }                        
                    }
                }
            }

            if (anyUpRelativeVolume)
            {
                //email result
                var client = new SmtpClient("smtp.gmail.com", 587) { EnableSsl = true };
                var from = new MailAddress("ssattin@gmail.com", "Simon Sattin");
                var message = new MailMessage(from, from)
                {
                    Subject = "Stocks up on relative volume"
                };
                var myCreds = new NetworkCredential("ssattin@gmail.com", "bergkamp_10", "");
                client.Credentials = myCreds;                                

                message.Body = sb.ToString();

                client.Send(message);
            }
        }

        private void button25_Click(object sender, EventArgs e)
        {
            var prices = DailyPriceDataAccess.GetAllDailyPricesBySymbol("PZZI");

            //var sbti = new ClosePriceStockBeeTradeIntensity7_65DayIndicator();
            //sbti.ApplyIndicator(prices);
        }

        private void button26_Click(object sender, EventArgs e)
        {
            var editor = new IBDStockListBroker();

            editor.UpdateStockList(new List<string>() { "FIRE", "CSTR", "GMCR" }, 423992736136534, "Test");

            editor.UpdateStockList(new List<string>(){ "OSIS", "SNI", "KORS" }, 425802493343449, "Holdings");
        }

        private void button27_Click(object sender, EventArgs e)
        {
            PriceBreachDataAccess.TruncatePriceBreachContender();

            PriceBreachDataAccess.InsertPriceBreachContender("NSM", 24, "Testing 123");
            PriceBreachDataAccess.InsertPriceBreachContender("KORS", 45, "Testing 123");
            PriceBreachDataAccess.InsertPriceBreachContender("GOOG", 650, "Testing 123");
        }

        private void button28_Click(object sender, EventArgs e)
        {
            var norgate = new NorgatePremiumDataStockFilePathsExtractor();
            var rsi = new ExponentialMovingAverageWilderRelativeStrengthIndexClosePriceDayIndicator(14, DayIndicatorNames.CLOSE_RSI14);

            var prices = norgate.GetStockPriceHistoryFromFilename(@"C:\Trading Data\Formatted Output\NASDAQ\AAPL.csv");

            Stopwatch sw = new Stopwatch();
            sw.Start();

            rsi.ApplyIndicator(prices);

            sw.Stop();
            Debug.WriteLine(string.Format("Total seconds taken: {0}", sw.Elapsed.TotalSeconds));
        }
    }   
}
